#include "MyTask.h"
#include "nlohmann/json.hpp"
#include <ctime>
#include <cstdlib>

using Json = nlohmann::json;

/* MyTask::MyTask(const string &msg,TcpConnectionPtr conn) */
/* :_msg(msg) */
MyTask::MyTask(const train_t &train,TcpConnectionPtr conn,
               KeyRecommander* pKeyRecommander,
               WebPageSearcher* pWebPageSearcher,
               LRUCache* pLRUCache)
    :_train(train)
    ,_conn(conn)
    ,_pKeyRecommander(pKeyRecommander)
    ,_pWebPageSearcher(pWebPageSearcher)
     ,_pLRUCache(pLRUCache)
{}

MyTask::~MyTask(){}

std::string MyTask::addEscapeToQuotes(const std::string& input) {
    std::string result;
    for (char c : input) {
        if(c == ' '){
            result += "\\";
        }else{
            result += c;
        }
    }
    return result;
}

string MyTask::delEscapeToQuotes(const std::string& input){
    string str = input;
    size_t pos = 0;
    while((pos = str.find("\\",pos)) != std::string::npos){
        str.replace(pos,1," ");
        pos += 1;
    }
    return str;
}

void MyTask::process(){
    //_msg;
    //在此处进行业务逻辑的处理decode,compute,encode
    //1.解析出要要查询的内容和类型
    Json Query = Json::parse(_train.jsonObj);
    string query = Query["query"];
    //2.拼接出存入缓存的关键字
    string key = std::to_string(_train.type) + query;
    //3.查看缓存中是否有此次查询的结果
    string JsonResult = _pLRUCache->get(key);
    /* cout << "cache.size() = " << _pLRUCache->_cache.size() << endl; */
    if(JsonResult.empty()){
        cout << key << endl;
        //缓存未命中,将查询结果直接返回给客户端
        if(_train.type == 1){
            _pKeyRecommander->doQuery(query,JsonResult);
        }else if(_train.type == 2){
            _pWebPageSearcher->doQuery(query,JsonResult);
        }
        //将得到的结果加入缓存
        _pLRUCache->put(key,JsonResult);
    }else{
        //缓存命中,去掉添加的转义字符
    }
    _train.length = JsonResult.size();
    _train.jsonObj = JsonResult;

    //msg1;
    //然后再讲处理好业务逻辑之后,线程池需要将处理好之后的
    //数据发给Reactor/EventLoop,然后通过EventLoop/Reactor
    //将数据发给客户端
    //
    //如果Reactor/EventLoop将数据打包成了MyTask之后,通过
    //addTask交给了线程池,然后Reactor应该继续去处理自己的事情
    //同时线程池中的线程应该处理Reactor交给线程池处理的任务
    //也就是Reactor与线程池各自干自己的事情。然后当线程池处理
    //好业务逻辑之后,应该主动通知Reactor将线程池处理好之后
    //的数据接走
    //
    //接下来的问题就是线程池与Reactor/EventLoop两类线程如何
    //进行通信？也就是线程如何通信
    //线程或者线程之间进行通信的方法eventfd如何使用？
    /* _conn->sendInLoop(_msg); */


    _conn->sendTrainInLoop(_train);
}
